package com.asset.dispoal.poi.documentation.service.commom;

import com.asset.dispoal.poi.documentation.domain.db.PlaintiffFileDo;
import com.asset.dispoal.poi.documentation.domain.db.mapper.DocumentationMapper;
import com.asset.dispoal.poi.documentation.dto.PlaintiffInfoRequest;
import com.asset.dispoal.poi.documentation.util.SealPictureRenderPolicy;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import lombok.SneakyThrows;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.file.FileUtil;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.ExecuteCmdUtil;
import tech.mhuang.pacebox.core.util.ZipUtil;
import tech.mhuang.pacebox.springboot.protocol.Result;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class DownloadPlaintiffInfoCommand implements BaseCommand<PlaintiffInfoRequest, Result> {

    @Autowired
    private DocumentationMapper documentationMapper;

    @Autowired
    private Environment environment;

    @Autowired
    private BaseIdeable<String> ideable;

    @SneakyThrows
    @Override
    public Result execute(PlaintiffInfoRequest request) {
        List<PlaintiffFileDo> plaintiffFileDoList = documentationMapper.queryPlaintiffFileById(request.getPlaintiffId());
        if (CollectionUtil.isEmpty(plaintiffFileDoList)) {
            return Result.faild("原告没有证据配置");
        }
        String headUrl = environment.getProperty("file.evidence.url");
        //营业执照（pdf）
        String businessUrl = plaintiffFileDoList.stream().filter(plaintiffFileDo -> plaintiffFileDo.getFileType().equals("business_license")).map(PlaintiffFileDo::getFileUrl).findFirst().get();
        //身份证明（word）
        String legalUrl = plaintiffFileDoList.stream().filter(plaintiffFileDo -> plaintiffFileDo.getFileType().equals("id_card")).map(PlaintiffFileDo::getFileUrl).findFirst().get();
        //法人身份证（word）
        String idcardUrl = plaintiffFileDoList.stream().filter(plaintiffFileDo -> plaintiffFileDo.getFileType().equals("legal_person_identification")).map(PlaintiffFileDo::getFileUrl).findFirst().get();
        //印章
        String stampUrl = plaintiffFileDoList.stream().filter(plaintiffFileDo -> plaintiffFileDo.getFileType().equals("stamp_file")).map(PlaintiffFileDo::getFileUrl).findFirst().get();
        String genUrl = headUrl + environment.getProperty("file.temp.url") + "/";
        String downloadFile = "/" + environment.getProperty("file.temp.url") + "/" + ideable.generateId();
        if (request.getSeal() == 1) {
            downloadFile = downloadFile + ".pdf";
            String businessFileName = ideable.generateId();
            //用印合并到一个pdf中
            //写营业执照
            PDDocument document = PDDocument.load(new File(headUrl + businessUrl));
            PDPage pdPage = document.getPage(0);
            PDImageXObject image = PDImageXObject.createFromFile(headUrl + stampUrl, document);
            PDPageContentStream pageStream = new PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.APPEND, true);
            pageStream.drawImage(image, 200, 400, 100, 100);
            pageStream.close();
            document.save(genUrl + "/" + businessFileName + ".pdf");
            document.close();

            String idCardFileName = ideable.generateId();
            //写身份证明
            Map<String, String> imageMap = new HashMap<>();
            imageMap.put("image", headUrl + stampUrl);
            ConfigureBuilder configureBuilder = Configure.builder().useSpringEL(false);
            configureBuilder.addPlugin('%', new SealPictureRenderPolicy());
            XWPFTemplate.compile(headUrl + legalUrl, configureBuilder.build()).render(imageMap).writeToFile(genUrl + "/" + idCardFileName + ".docx");
            //此处将word转pdf
            executeFileCommand(genUrl + "/" + idCardFileName + ".docx", genUrl);
            //写身份证
            //此处将word转pdf
            executeFileCommand(headUrl + idcardUrl, genUrl);
            //合并PDF后返回对应下载的地址。提供给前端进行下载
            //合并的文件
            new File(headUrl + "/" + downloadFile).createNewFile();
            PDFMergerUtility pdfMerger = new PDFMergerUtility();
            pdfMerger.setDestinationFileName(headUrl + "/" + downloadFile);
            pdfMerger.addSource(genUrl + "/" + businessFileName + ".pdf");
            pdfMerger.addSource(genUrl + "/" + idCardFileName + ".pdf");
            String imageUrl = new File(headUrl + idcardUrl).getName();
            pdfMerger.addSource(genUrl + "/" + imageUrl.substring(0, imageUrl.lastIndexOf(".")) + ".pdf");
            pdfMerger.mergeDocuments(null);
        } else {
            downloadFile = downloadFile + ".zip";
            File downloadFileZip = new File(headUrl + "/" + downloadFile);
            downloadFileZip.createNewFile();
            //不用印 则下载3个文件。营业执照、法人证明、法人身份证进行打包
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            List<File> fileList = new ArrayList<>();
            fileList.add(new File(headUrl + businessUrl));
            fileList.add(new File(headUrl + legalUrl));
            fileList.add(new File(headUrl + idcardUrl));
            ZipUtil.toZip(fileList, outputStream);
            FileUtil.writeByteArrayToFile(downloadFileZip, outputStream.toByteArray());
        }

        return Result.ok(downloadFile);
    }

    private String getOsName() {
        return System.getProperty("os.name");
    }

    private void executeFileCommand(String src, String dest) throws IOException, InterruptedException {
        String cmd;
        if (getOsName().startsWith("Linux")) {
            cmd = "Libreoffice7.4 --headless --convert-to pdf --outdir " + dest + " " + src;
        } else {
            cmd = "soffice --headless --convert-to pdf " + new File(src) + " --outdir " + new File(dest);
        }

        ExecuteCmdUtil.executeCmdSingle(cmd);
    }
}
